package com.fdb.efp.flow.service;

import com.fdb.basic.framework.core.cache.Cache;
import com.fdb.basic.framework.core.cache.PiccsFrameworkCache;
import com.fdb.basic.framework.core.util.BeanUtility;
import com.fdb.basic.framework.core.util.SpringContextUtils;
import com.fdb.basic.framework.core.util.StringUtil;
import com.fdb.basic.framework.core.vo.OrgInfoCacheVO;
import com.fdb.basic.framework.core.vo.UserInfoCacheVO;
import com.fdb.efp.console.common.ConsoleConstant;
import com.fdb.efp.console.service.facade.SDutyService;
import com.fdb.efp.flow.common.constance.FlowConstance;
import com.fdb.efp.flow.service.facade.BizFlowProcessService;
import com.fdb.efp.flow.service.vo.BizFlowProcessVO;
import com.fdb.efp.riskm.service.facade.CooprOrgInfoService;
import com.fdb.efp.riskm.service.vo.CooprOrgInfoVO;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.*;

import static com.fdb.basic.framework.core.constant.CacheConstant.CACHE_KEY_ORG_INFOS;
import static com.fdb.basic.framework.core.constant.CacheConstant.CACHE_KEY_USER_INFOS;

/**
 * 需求编号【2019D0509】
 * flow.front工程的公共服务类
 * @author qiuyf
 * @version 0.1 初始为0.1,后续变更则修改
 * @since 2019/9/30 15:37
 */
@Service("flowCommonService")
public class FlowCommonService {

    /**
     * 日志信息
     */
    private final Logger logger = LoggerFactory.getLogger(FlowCommonService.class);

    @Autowired
    @Qualifier("cooprOrgInfoService")
    private CooprOrgInfoService cooprOrgInfoService;

    @Autowired
    @Qualifier("bizFlowProcessService")
    private BizFlowProcessService bizFlowProcessService;

    @Autowired
    @Qualifier("sDutyService")
    private SDutyService sDutyService;

    public final <T> T displayOrgName(T data, String srcColumn, String targetColumn) {
        try {
            // 获取机构缓存
            PiccsFrameworkCache bean = (PiccsFrameworkCache) SpringContextUtils.getBean(Cache.CACHE_BEAN);
            Map<String, OrgInfoCacheVO> orgInfoCacheVOMap = bean.get(CACHE_KEY_ORG_INFOS);
            if (Objects.nonNull(orgInfoCacheVOMap) && Objects.nonNull(data) && StringUtil.isNotEmpty(srcColumn) && StringUtil.isNotEmpty(targetColumn)) {
                if (data instanceof List) {
                    List list = (List) data;
                    for (Object o : list) {
                        String code = StringUtil.replaceObjNull(BeanUtility.getProptery(o, srcColumn));
                        if (StringUtil.isNotEmpty(code)) {
                            Object cacheObject = orgInfoCacheVOMap.get(code);
                            if (Objects.nonNull(cacheObject)) {
                                Object displayName = BeanUtility.getProptery(cacheObject, "orgName");
                                BeanUtility.setProptery(o, targetColumn, displayName);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("当前字段：" + srcColumn + ", 目标字段：" + targetColumn + "转换翻译出现异常!", e);
        }
        return data;
    }

    public final <T> T displayUserName(T data, String srcColumn, String targetColumn) {
        try {
            // 获取机构缓存
            PiccsFrameworkCache bean = (PiccsFrameworkCache) SpringContextUtils.getBean(Cache.CACHE_BEAN);
            Map<String, UserInfoCacheVO> userInfoCacheVOMap = bean.get(CACHE_KEY_USER_INFOS);
            if (Objects.nonNull(userInfoCacheVOMap) && Objects.nonNull(data) && StringUtil.isNotEmpty(srcColumn) && StringUtil.isNotEmpty(targetColumn)) {
                if (data instanceof List) {
                    List list = (List) data;
                    for (Object o : list) {
                        String code = StringUtil.replaceObjNull(BeanUtility.getProptery(o, srcColumn));
                        if (StringUtil.isNotEmpty(code)) {
                            Object cacheObject = userInfoCacheVOMap.get(code);
                            if (Objects.nonNull(cacheObject)) {
                                Object displayName = BeanUtility.getProptery(cacheObject, "userName");
                                BeanUtility.setProptery(o, targetColumn, displayName);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("当前字段：" + srcColumn + ", 目标字段：" + targetColumn + "转换翻译出现异常!", e);
        }
        return data;
    }

    public static String getMarkSaid(int numerrator, int denominator) {
        if (denominator == 0) {
            return null;
        }
        if (numerrator == 0) {
            return String.valueOf(numerrator);
        }
        int maxCommDivNum = getMaxCommDiv(numerrator, denominator);
        return (numerrator / maxCommDivNum) + "/" + (denominator / maxCommDivNum);
    }

    /**
     * 求最大公约数
     *
     * @param n
     * @param d
     * @return
     */
    private static int getMaxCommDiv(int n, int d) {
        if (n < d) {
            int temp = n;
            n = d;
            d = temp;
        }
        int p = n % d;
        while (p != 0) {
            n = d;
            d = p;
            p = n % d;
        }
        return d;
    }

    /**
     * 获取合作状态为"正常"的委外机构 【来自表 coopr_org_info】
     *
     * @return
     */
    public List<CooprOrgInfoVO> getDistrCooprOrgInfos(String cooprOrgType) throws Exception {
        CooprOrgInfoVO cooprOrgInfoVO = new CooprOrgInfoVO();
        cooprOrgInfoVO.setCooprOrgType(cooprOrgType);
        List<CooprOrgInfoVO> result = Optional.ofNullable(cooprOrgInfoService.getAllCooprOrgs(cooprOrgInfoVO))
                .orElseThrow(() -> new Exception("暂无可参与分案的合作机构，请先配置。"));
        return result;
    }

    /**
     * 从HttpServletRequest中获取文件
     *
     * @author
     * @version
     * @since
     */
    @SuppressWarnings("rawtypes")
    public List<File> getFileList(HttpServletRequest request) throws IOException {
        List<File> listFiles = new ArrayList<File>();
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        if (multipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            Iterator iter = multiRequest.getFileNames();
            while (iter.hasNext()) {
                MultipartFile mFile = multiRequest.getFile(iter.next().toString());
                if (mFile != null) {
                    listFiles.add(multipartToFile(mFile));
                }
            }
        }
        return listFiles;
    }

    /**
     * 转换文件
     *
     * @author
     * @version
     * @since
     */
    private File multipartToFile(MultipartFile multfile) throws IOException {
        CommonsMultipartFile cmf = (CommonsMultipartFile) multfile;
        DiskFileItem dfi = (DiskFileItem) cmf.getFileItem();
        File file = dfi.getStoreLocation();
        if (file.length() < 2048) {
            File tmpFile = new File(System.getProperty("java.io.tmpdir") + System.getProperty("file.separator") + file.getName());
            multfile.transferTo(tmpFile);
            return tmpFile;
        }
        return file;
    }

    /**
     * 流程岗位验证（流程配置的岗位失效或删除，控制不能发起流程）
     * @author xiezw
     * @params  * @param bizFlowId
     * @return
     * @date 2019/12/6 14:39
     * @version 0.1
     */
    public boolean dutyFlowCheck(String bizEventId, String bizFlowId){
        BizFlowProcessVO bizFlowProcessVO = new BizFlowProcessVO();
        bizFlowProcessVO.setBizEventId(bizEventId);
        bizFlowProcessVO.setBizFlowId(bizFlowId);
        List<BizFlowProcessVO> list = bizFlowProcessService.queryAllByEventIdAndFlowId(bizFlowProcessVO);
        if(list != null && list.size()>0){
            for (BizFlowProcessVO item :list){
                if(item != null && item.getBizNodeDutyNo()!=null && FlowConstance.NODE_TYPE_APPROVE.equals(item.getBizNodeType()) &&
                        !(ConsoleConstant.COMMON_STATUS_1.equals(sDutyService.queryStatusByDutyCode(item.getBizNodeDutyNo())))){
                    logger.info(">=================流程岗位已失效====================<");
                    return false;
                }
            }
        }
        return true;
    }

}
